/*
 * Copyright 2014 MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mongoc-prelude.h"


#ifndef MONGOC_SCRAM_PRIVATE_H
#define MONGOC_SCRAM_PRIVATE_H


#include <bson/bson.h>
#include "mongoc-crypto-private.h"


BSON_BEGIN_DECLS

#define MONGOC_SCRAM_SHA_1_HASH_SIZE 20
#define MONGOC_SCRAM_SHA_256_HASH_SIZE 32
/* SCRAM-SHA-1 uses a hash size of 20, and SCRAM-SHA-256 uses a hash size
 * of 32. Stack allocations should be large enough for either. */
#define MONGOC_SCRAM_HASH_MAX_SIZE MONGOC_SCRAM_SHA_256_HASH_SIZE

#define MONGOC_SCRAM_B64_ENCODED_SIZE(n) (2 * n)

#define MONGOC_SCRAM_B64_HASH_MAX_SIZE \
   MONGOC_SCRAM_B64_ENCODED_SIZE (MONGOC_SCRAM_HASH_MAX_SIZE)

enum {
   /* It is unlikely that there will be more than 64 different user accounts
    * used in a single process */
   MONGOC_SCRAM_CACHE_SIZE = 64,
};

typedef struct _mongoc_scram_t {
   int step;
   char *user;
   char *pass;
   char hashed_password[MONGOC_SCRAM_HASH_MAX_SIZE];
   uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE];
   uint32_t iterations;
   uint8_t client_key[MONGOC_SCRAM_HASH_MAX_SIZE];
   uint8_t server_key[MONGOC_SCRAM_HASH_MAX_SIZE];
   uint8_t salted_password[MONGOC_SCRAM_HASH_MAX_SIZE];
   char encoded_nonce[48];
   int32_t encoded_nonce_len;
   uint8_t *auth_message;
   uint32_t auth_messagemax;
   uint32_t auth_messagelen;
#ifdef MONGOC_ENABLE_CRYPTO
   mongoc_crypto_t crypto;
#endif
} mongoc_scram_t;

#ifdef MONGOC_ENABLE_CRYPTO
void
_mongoc_scram_init (mongoc_scram_t *scram, mongoc_crypto_hash_algorithm_t algo);
#endif

void
_mongoc_scram_set_pass (mongoc_scram_t *scram, const char *pass);

void
_mongoc_scram_set_user (mongoc_scram_t *scram, const char *user);

void
_mongoc_scram_set_server_key (mongoc_scram_t *scram,
                              const uint8_t *server_key,
                              size_t len);

void
_mongoc_scram_set_salted_password (mongoc_scram_t *scram,
                                   const uint8_t *salted_password,
                                   size_t len);

void
_mongoc_scram_destroy (mongoc_scram_t *scram);

bool
_mongoc_scram_step (mongoc_scram_t *scram,
                    const uint8_t *inbuf,
                    uint32_t inbuflen,
                    uint8_t *outbuf,
                    uint32_t outbufmax,
                    uint32_t *outbuflen,
                    bson_error_t *error);

/* returns false if this string does not need SASLPrep. It returns true
 * conservatively, if str might need to be SASLPrep'ed. */
bool
_mongoc_sasl_prep_required (const char *str);

/* returns the output of SASLPrep as a new string which must be freed. Returns
 * null on error and sets err. */
char *
_mongoc_sasl_prep (const char *in_utf8, bson_error_t *err);

/* returns the byte length of the first UTF-8 code point in `s`.
 * _mongoc_utf8_char_length is exposed for testing */
size_t
_mongoc_utf8_char_length (const char *s);

/* returns the byte length of the UTF-8 string. Returns -1 if `s` is not a valid
 * UTF-8 string.
 * _mongoc_utf8_string_length is exposed for testing. */
ssize_t
_mongoc_utf8_string_length (const char *s);

/* returns the first Unicode code point in `c`. Returns 0 if length is 0.
 * `c` must be a valid UTF-8 string.
 * _mongoc_utf8_get_first_code_point is exposed for testing. */
uint32_t
_mongoc_utf8_get_first_code_point (const char *c, size_t length);

/* the tables below all come from RFC 3454. They are all range tables, with
 * value 2*n being the lower bound, and value 2*n + 1 being the upper bound.
 * Both bounds are exclusive.
 */

/* A.1 Unassigned code points in Unicode 3.2
 * these characters are not allowed for SASLPrep
 */
static const uint32_t unassigned_codepoint_ranges[] = {
   0x0221,  0x0221,  0x0234,  0x024F,  0x02AE,  0x02AF,  0x02EF,  0x02FF,
   0x0350,  0x035F,  0x0370,  0x0373,  0x0376,  0x0379,  0x037B,  0x037D,
   0x037F,  0x0383,  0x038B,  0x038B,  0x038D,  0x038D,  0x03A2,  0x03A2,
   0x03CF,  0x03CF,  0x03F7,  0x03FF,  0x0487,  0x0487,  0x04CF,  0x04CF,
   0x04F6,  0x04F7,  0x04FA,  0x04FF,  0x0510,  0x0530,  0x0557,  0x0558,
   0x0560,  0x0560,  0x0588,  0x0588,  0x058B,  0x0590,  0x05A2,  0x05A2,
   0x05BA,  0x05BA,  0x05C5,  0x05CF,  0x05EB,  0x05EF,  0x05F5,  0x060B,
   0x060D,  0x061A,  0x061C,  0x061E,  0x0620,  0x0620,  0x063B,  0x063F,
   0x0656,  0x065F,  0x06EE,  0x06EF,  0x06FF,  0x06FF,  0x070E,  0x070E,
   0x072D,  0x072F,  0x074B,  0x077F,  0x07B2,  0x0900,  0x0904,  0x0904,
   0x093A,  0x093B,  0x094E,  0x094F,  0x0955,  0x0957,  0x0971,  0x0980,
   0x0984,  0x0984,  0x098D,  0x098E,  0x0991,  0x0992,  0x09A9,  0x09A9,
   0x09B1,  0x09B1,  0x09B3,  0x09B5,  0x09BA,  0x09BB,  0x09BD,  0x09BD,
   0x09C5,  0x09C6,  0x09C9,  0x09CA,  0x09CE,  0x09D6,  0x09D8,  0x09DB,
   0x09DE,  0x09DE,  0x09E4,  0x09E5,  0x09FB,  0x0A01,  0x0A03,  0x0A04,
   0x0A0B,  0x0A0E,  0x0A11,  0x0A12,  0x0A29,  0x0A29,  0x0A31,  0x0A31,
   0x0A34,  0x0A34,  0x0A37,  0x0A37,  0x0A3A,  0x0A3B,  0x0A3D,  0x0A3D,
   0x0A43,  0x0A46,  0x0A49,  0x0A4A,  0x0A4E,  0x0A58,  0x0A5D,  0x0A5D,
   0x0A5F,  0x0A65,  0x0A75,  0x0A80,  0x0A84,  0x0A84,  0x0A8C,  0x0A8C,
   0x0A8E,  0x0A8E,  0x0A92,  0x0A92,  0x0AA9,  0x0AA9,  0x0AB1,  0x0AB1,
   0x0AB4,  0x0AB4,  0x0ABA,  0x0ABB,  0x0AC6,  0x0AC6,  0x0ACA,  0x0ACA,
   0x0ACE,  0x0ACF,  0x0AD1,  0x0ADF,  0x0AE1,  0x0AE5,  0x0AF0,  0x0B00,
   0x0B04,  0x0B04,  0x0B0D,  0x0B0E,  0x0B11,  0x0B12,  0x0B29,  0x0B29,
   0x0B31,  0x0B31,  0x0B34,  0x0B35,  0x0B3A,  0x0B3B,  0x0B44,  0x0B46,
   0x0B49,  0x0B4A,  0x0B4E,  0x0B55,  0x0B58,  0x0B5B,  0x0B5E,  0x0B5E,
   0x0B62,  0x0B65,  0x0B71,  0x0B81,  0x0B84,  0x0B84,  0x0B8B,  0x0B8D,
   0x0B91,  0x0B91,  0x0B96,  0x0B98,  0x0B9B,  0x0B9B,  0x0B9D,  0x0B9D,
   0x0BA0,  0x0BA2,  0x0BA5,  0x0BA7,  0x0BAB,  0x0BAD,  0x0BB6,  0x0BB6,
   0x0BBA,  0x0BBD,  0x0BC3,  0x0BC5,  0x0BC9,  0x0BC9,  0x0BCE,  0x0BD6,
   0x0BD8,  0x0BE6,  0x0BF3,  0x0C00,  0x0C04,  0x0C04,  0x0C0D,  0x0C0D,
   0x0C11,  0x0C11,  0x0C29,  0x0C29,  0x0C34,  0x0C34,  0x0C3A,  0x0C3D,
   0x0C45,  0x0C45,  0x0C49,  0x0C49,  0x0C4E,  0x0C54,  0x0C57,  0x0C5F,
   0x0C62,  0x0C65,  0x0C70,  0x0C81,  0x0C84,  0x0C84,  0x0C8D,  0x0C8D,
   0x0C91,  0x0C91,  0x0CA9,  0x0CA9,  0x0CB4,  0x0CB4,  0x0CBA,  0x0CBD,
   0x0CC5,  0x0CC5,  0x0CC9,  0x0CC9,  0x0CCE,  0x0CD4,  0x0CD7,  0x0CDD,
   0x0CDF,  0x0CDF,  0x0CE2,  0x0CE5,  0x0CF0,  0x0D01,  0x0D04,  0x0D04,
   0x0D0D,  0x0D0D,  0x0D11,  0x0D11,  0x0D29,  0x0D29,  0x0D3A,  0x0D3D,
   0x0D44,  0x0D45,  0x0D49,  0x0D49,  0x0D4E,  0x0D56,  0x0D58,  0x0D5F,
   0x0D62,  0x0D65,  0x0D70,  0x0D81,  0x0D84,  0x0D84,  0x0D97,  0x0D99,
   0x0DB2,  0x0DB2,  0x0DBC,  0x0DBC,  0x0DBE,  0x0DBF,  0x0DC7,  0x0DC9,
   0x0DCB,  0x0DCE,  0x0DD5,  0x0DD5,  0x0DD7,  0x0DD7,  0x0DE0,  0x0DF1,
   0x0DF5,  0x0E00,  0x0E3B,  0x0E3E,  0x0E5C,  0x0E80,  0x0E83,  0x0E83,
   0x0E85,  0x0E86,  0x0E89,  0x0E89,  0x0E8B,  0x0E8C,  0x0E8E,  0x0E93,
   0x0E98,  0x0E98,  0x0EA0,  0x0EA0,  0x0EA4,  0x0EA4,  0x0EA6,  0x0EA6,
   0x0EA8,  0x0EA9,  0x0EAC,  0x0EAC,  0x0EBA,  0x0EBA,  0x0EBE,  0x0EBF,
   0x0EC5,  0x0EC5,  0x0EC7,  0x0EC7,  0x0ECE,  0x0ECF,  0x0EDA,  0x0EDB,
   0x0EDE,  0x0EFF,  0x0F48,  0x0F48,  0x0F6B,  0x0F70,  0x0F8C,  0x0F8F,
   0x0F98,  0x0F98,  0x0FBD,  0x0FBD,  0x0FCD,  0x0FCE,  0x0FD0,  0x0FFF,
   0x1022,  0x1022,  0x1028,  0x1028,  0x102B,  0x102B,  0x1033,  0x1035,
   0x103A,  0x103F,  0x105A,  0x109F,  0x10C6,  0x10CF,  0x10F9,  0x10FA,
   0x10FC,  0x10FF,  0x115A,  0x115E,  0x11A3,  0x11A7,  0x11FA,  0x11FF,
   0x1207,  0x1207,  0x1247,  0x1247,  0x1249,  0x1249,  0x124E,  0x124F,
   0x1257,  0x1257,  0x1259,  0x1259,  0x125E,  0x125F,  0x1287,  0x1287,
   0x1289,  0x1289,  0x128E,  0x128F,  0x12AF,  0x12AF,  0x12B1,  0x12B1,
   0x12B6,  0x12B7,  0x12BF,  0x12BF,  0x12C1,  0x12C1,  0x12C6,  0x12C7,
   0x12CF,  0x12CF,  0x12D7,  0x12D7,  0x12EF,  0x12EF,  0x130F,  0x130F,
   0x1311,  0x1311,  0x1316,  0x1317,  0x131F,  0x131F,  0x1347,  0x1347,
   0x135B,  0x1360,  0x137D,  0x139F,  0x13F5,  0x1400,  0x1677,  0x167F,
   0x169D,  0x169F,  0x16F1,  0x16FF,  0x170D,  0x170D,  0x1715,  0x171F,
   0x1737,  0x173F,  0x1754,  0x175F,  0x176D,  0x176D,  0x1771,  0x1771,
   0x1774,  0x177F,  0x17DD,  0x17DF,  0x17EA,  0x17FF,  0x180F,  0x180F,
   0x181A,  0x181F,  0x1878,  0x187F,  0x18AA,  0x1DFF,  0x1E9C,  0x1E9F,
   0x1EFA,  0x1EFF,  0x1F16,  0x1F17,  0x1F1E,  0x1F1F,  0x1F46,  0x1F47,
   0x1F4E,  0x1F4F,  0x1F58,  0x1F58,  0x1F5A,  0x1F5A,  0x1F5C,  0x1F5C,
   0x1F5E,  0x1F5E,  0x1F7E,  0x1F7F,  0x1FB5,  0x1FB5,  0x1FC5,  0x1FC5,
   0x1FD4,  0x1FD5,  0x1FDC,  0x1FDC,  0x1FF0,  0x1FF1,  0x1FF5,  0x1FF5,
   0x1FFF,  0x1FFF,  0x2053,  0x2056,  0x2058,  0x205E,  0x2064,  0x2069,
   0x2072,  0x2073,  0x208F,  0x209F,  0x20B2,  0x20CF,  0x20EB,  0x20FF,
   0x213B,  0x213C,  0x214C,  0x2152,  0x2184,  0x218F,  0x23CF,  0x23FF,
   0x2427,  0x243F,  0x244B,  0x245F,  0x24FF,  0x24FF,  0x2614,  0x2615,
   0x2618,  0x2618,  0x267E,  0x267F,  0x268A,  0x2700,  0x2705,  0x2705,
   0x270A,  0x270B,  0x2728,  0x2728,  0x274C,  0x274C,  0x274E,  0x274E,
   0x2753,  0x2755,  0x2757,  0x2757,  0x275F,  0x2760,  0x2795,  0x2797,
   0x27B0,  0x27B0,  0x27BF,  0x27CF,  0x27EC,  0x27EF,  0x2B00,  0x2E7F,
   0x2E9A,  0x2E9A,  0x2EF4,  0x2EFF,  0x2FD6,  0x2FEF,  0x2FFC,  0x2FFF,
   0x3040,  0x3040,  0x3097,  0x3098,  0x3100,  0x3104,  0x312D,  0x3130,
   0x318F,  0x318F,  0x31B8,  0x31EF,  0x321D,  0x321F,  0x3244,  0x3250,
   0x327C,  0x327E,  0x32CC,  0x32CF,  0x32FF,  0x32FF,  0x3377,  0x337A,
   0x33DE,  0x33DF,  0x33FF,  0x33FF,  0x4DB6,  0x4DFF,  0x9FA6,  0x9FFF,
   0xA48D,  0xA48F,  0xA4C7,  0xABFF,  0xD7A4,  0xD7FF,  0xFA2E,  0xFA2F,
   0xFA6B,  0xFAFF,  0xFB07,  0xFB12,  0xFB18,  0xFB1C,  0xFB37,  0xFB37,
   0xFB3D,  0xFB3D,  0xFB3F,  0xFB3F,  0xFB42,  0xFB42,  0xFB45,  0xFB45,
   0xFBB2,  0xFBD2,  0xFD40,  0xFD4F,  0xFD90,  0xFD91,  0xFDC8,  0xFDCF,
   0xFDFD,  0xFDFF,  0xFE10,  0xFE1F,  0xFE24,  0xFE2F,  0xFE47,  0xFE48,
   0xFE53,  0xFE53,  0xFE67,  0xFE67,  0xFE6C,  0xFE6F,  0xFE75,  0xFE75,
   0xFEFD,  0xFEFE,  0xFF00,  0xFF00,  0xFFBF,  0xFFC1,  0xFFC8,  0xFFC9,
   0xFFD0,  0xFFD1,  0xFFD8,  0xFFD9,  0xFFDD,  0xFFDF,  0xFFE7,  0xFFE7,
   0xFFEF,  0xFFF8,  0x10000, 0x102FF, 0x1031F, 0x1031F, 0x10324, 0x1032F,
   0x1034B, 0x103FF, 0x10426, 0x10427, 0x1044E, 0x1CFFF, 0x1D0F6, 0x1D0FF,
   0x1D127, 0x1D129, 0x1D1DE, 0x1D3FF, 0x1D455, 0x1D455, 0x1D49D, 0x1D49D,
   0x1D4A0, 0x1D4A1, 0x1D4A3, 0x1D4A4, 0x1D4A7, 0x1D4A8, 0x1D4AD, 0x1D4AD,
   0x1D4BA, 0x1D4BA, 0x1D4BC, 0x1D4BC, 0x1D4C1, 0x1D4C1, 0x1D4C4, 0x1D4C4,
   0x1D506, 0x1D506, 0x1D50B, 0x1D50C, 0x1D515, 0x1D515, 0x1D51D, 0x1D51D,
   0x1D53A, 0x1D53A, 0x1D53F, 0x1D53F, 0x1D545, 0x1D545, 0x1D547, 0x1D549,
   0x1D551, 0x1D551, 0x1D6A4, 0x1D6A7, 0x1D7CA, 0x1D7CD, 0x1D800, 0x1FFFD,
   0x2A6D7, 0x2F7FF, 0x2FA1E, 0x2FFFD, 0x30000, 0x3FFFD, 0x40000, 0x4FFFD,
   0x50000, 0x5FFFD, 0x60000, 0x6FFFD, 0x70000, 0x7FFFD, 0x80000, 0x8FFFD,
   0x90000, 0x9FFFD, 0xA0000, 0xAFFFD, 0xB0000, 0xBFFFD, 0xC0000, 0xCFFFD,
   0xD0000, 0xDFFFD, 0xE0000, 0xE0000, 0xE0002, 0xE001F, 0xE0080, 0xEFFFD};

/*
 * Table B.1 Commonly mapped to nothing
 * these are all of the characters that will be mapped to nothing.
 */
static const uint32_t commonly_mapped_to_nothing_ranges[] = {0x00AD,
                                                             0x00AD,
                                                             0x034F,
                                                             0x034F,
                                                             0x1806,
                                                             0x1806,
                                                             0x180B,
                                                             0x180D,
                                                             0x200B,
                                                             0x200D,
                                                             0x2060,
                                                             0x2060,
                                                             0xFE00,
                                                             0xFE0F,
                                                             0xFEFF,
                                                             0xFEFF};

/*
 * Table C.1.2 Non-ASCII space characters
 * these are all of the characters that will be mapped to the space character.
 * (0x0020)
 */
static const uint32_t non_ascii_space_character_ranges[] = {0x00A0,
                                                            0x00A0,
                                                            0x1680,
                                                            0x1680,
                                                            0x2000,
                                                            0x200B,
                                                            0x202F,
                                                            0x202F,
                                                            0x205F,
                                                            0x205F,
                                                            0x3000,
                                                            0x3000};

/*
 * these are all of the characters that are "prohibited output" for SASLprep.
 * The tables that they come from are listed.
 */
static const uint32_t prohibited_output_ranges[] = {
   0x0000,   0x001F,  /* C.2.1 */
   0x007F,   0x00A0,  /* C.1.2, C.2.1, C.2.2 */
   0x0340,   0x0341,  /* C.8 */
   0x06DD,   0x06DD,  /* C.2.2 */
   0x070F,   0x070F,  /* C.2.2 */
   0x1680,   0x1680,  /* C.1.2 */
   0x180E,   0x180E,  /* C.2.2 */
   0x2000,   0x200F,  /* C.1.2, C.2.2, C.8 */
   0x2028,   0x202F,  /* C.1.2, C.2.2, C.8 */
   0x205F,   0x2063,  /* C.1.2, C.2.2 */
   0x206A,   0x206F,  /* C.2.2, C.8 */
   0x2FF0,   0x2FFB,  /* C.7 */
   0x3000,   0x3000,  /* C.1.2 */
   0xD800,   0xF8FF,  /* C.3, C.5 */
   0xFDD0,   0xFDEF,  /* C.4 */
   0xFEFF,   0xFEFF,  /* C.2.2 */
   0xFFF9,   0xFFFF,  /* C.2.2, C.4, C.6 */
   0x1D173,  0x1D17A, /* C.2.2 */
   0x1FFFE,  0x1FFFF, /* C.4 */
   0x2FFFE,  0x2FFFF, /* C.4 */
   0x3FFFE,  0x3FFFF, /* C.4 */
   0x4FFFE,  0x4FFFF, /* C.4 */
   0x5FFFE,  0x5FFFF, /* C.4 */
   0x6FFFE,  0x6FFFF, /* C.4 */
   0x7FFFE,  0x7FFFF, /* C.4 */
   0x8FFFE,  0x8FFFF, /* C.4 */
   0x9FFFE,  0x9FFFF, /* C.4 */
   0xAFFFE,  0xAFFFF, /* C.4 */
   0xBFFFE,  0xBFFFF, /* C.4 */
   0xCFFFE,  0xCFFFF, /* C.4 */
   0xDFFFE,  0xDFFFF, /* C.4 */
   0xE0001,  0xE0001, /* C.9 */
   0xE0020,  0xE007F, /* C.9 */
   0xEFFFE,  0xEFFFF, /* C.4 */
   0xF0000,  0xFFFFF, /* C.3, C.4 */
   0x100000, 0x10FFFF /* C.3, C.4 */
};

/* D.1 Characters with bidirectional property "R" or "AL"
 * any string that contains one of these characters cannot contain a character
 * with bidirectional property "L".
 */

static const uint32_t RandALCat_bidi_ranges[] = {
   0x05BE, 0x05BE, 0x05C0, 0x05C0, 0x05C3, 0x05C3, 0x05D0, 0x05EA, 0x05F0,
   0x05F4, 0x061B, 0x061B, 0x061F, 0x061F, 0x0621, 0x063A, 0x0640, 0x064A,
   0x066D, 0x066F, 0x0671, 0x06D5, 0x06DD, 0x06DD, 0x06E5, 0x06E6, 0x06FA,
   0x06FE, 0x0700, 0x070D, 0x0710, 0x0710, 0x0712, 0x072C, 0x0780, 0x07A5,
   0x07B1, 0x07B1, 0x200F, 0x200F, 0xFB1D, 0xFB1D, 0xFB1F, 0xFB28, 0xFB2A,
   0xFB36, 0xFB38, 0xFB3C, 0xFB3E, 0xFB3E, 0xFB40, 0xFB41, 0xFB43, 0xFB44,
   0xFB46, 0xFBB1, 0xFBD3, 0xFD3D, 0xFD50, 0xFD8F, 0xFD92, 0xFDC7, 0xFDF0,
   0xFDFC, 0xFE70, 0xFE74, 0xFE76, 0xFEFC};

/* D.2 Characters with bidirectional property "L"
 * any string that contains one of these characters cannot contain a character
 * with bidirectional property "R" or "AL".
 * */
static const uint32_t LCat_bidi_ranges[] = {
   0x0041,  0x005A,  0x0061,  0x007A,  0x00AA,  0x00AA,  0x00B5,   0x00B5,
   0x00BA,  0x00BA,  0x00C0,  0x00D6,  0x00D8,  0x00F6,  0x00F8,   0x0220,
   0x0222,  0x0233,  0x0250,  0x02AD,  0x02B0,  0x02B8,  0x02BB,   0x02C1,
   0x02D0,  0x02D1,  0x02E0,  0x02E4,  0x02EE,  0x02EE,  0x037A,   0x037A,
   0x0386,  0x0386,  0x0388,  0x038A,  0x038C,  0x038C,  0x038E,   0x03A1,
   0x03A3,  0x03CE,  0x03D0,  0x03F5,  0x0400,  0x0482,  0x048A,   0x04CE,
   0x04D0,  0x04F5,  0x04F8,  0x04F9,  0x0500,  0x050F,  0x0531,   0x0556,
   0x0559,  0x055F,  0x0561,  0x0587,  0x0589,  0x0589,  0x0903,   0x0903,
   0x0905,  0x0939,  0x093D,  0x0940,  0x0949,  0x094C,  0x0950,   0x0950,
   0x0958,  0x0961,  0x0964,  0x0970,  0x0982,  0x0983,  0x0985,   0x098C,
   0x098F,  0x0990,  0x0993,  0x09A8,  0x09AA,  0x09B0,  0x09B2,   0x09B2,
   0x09B6,  0x09B9,  0x09BE,  0x09C0,  0x09C7,  0x09C8,  0x09CB,   0x09CC,
   0x09D7,  0x09D7,  0x09DC,  0x09DD,  0x09DF,  0x09E1,  0x09E6,   0x09F1,
   0x09F4,  0x09FA,  0x0A05,  0x0A0A,  0x0A0F,  0x0A10,  0x0A13,   0x0A28,
   0x0A2A,  0x0A30,  0x0A32,  0x0A33,  0x0A35,  0x0A36,  0x0A38,   0x0A39,
   0x0A3E,  0x0A40,  0x0A59,  0x0A5C,  0x0A5E,  0x0A5E,  0x0A66,   0x0A6F,
   0x0A72,  0x0A74,  0x0A83,  0x0A83,  0x0A85,  0x0A8B,  0x0A8D,   0x0A8D,
   0x0A8F,  0x0A91,  0x0A93,  0x0AA8,  0x0AAA,  0x0AB0,  0x0AB2,   0x0AB3,
   0x0AB5,  0x0AB9,  0x0ABD,  0x0AC0,  0x0AC9,  0x0AC9,  0x0ACB,   0x0ACC,
   0x0AD0,  0x0AD0,  0x0AE0,  0x0AE0,  0x0AE6,  0x0AEF,  0x0B02,   0x0B03,
   0x0B05,  0x0B0C,  0x0B0F,  0x0B10,  0x0B13,  0x0B28,  0x0B2A,   0x0B30,
   0x0B32,  0x0B33,  0x0B36,  0x0B39,  0x0B3D,  0x0B3E,  0x0B40,   0x0B40,
   0x0B47,  0x0B48,  0x0B4B,  0x0B4C,  0x0B57,  0x0B57,  0x0B5C,   0x0B5D,
   0x0B5F,  0x0B61,  0x0B66,  0x0B70,  0x0B83,  0x0B83,  0x0B85,   0x0B8A,
   0x0B8E,  0x0B90,  0x0B92,  0x0B95,  0x0B99,  0x0B9A,  0x0B9C,   0x0B9C,
   0x0B9E,  0x0B9F,  0x0BA3,  0x0BA4,  0x0BA8,  0x0BAA,  0x0BAE,   0x0BB5,
   0x0BB7,  0x0BB9,  0x0BBE,  0x0BBF,  0x0BC1,  0x0BC2,  0x0BC6,   0x0BC8,
   0x0BCA,  0x0BCC,  0x0BD7,  0x0BD7,  0x0BE7,  0x0BF2,  0x0C01,   0x0C03,
   0x0C05,  0x0C0C,  0x0C0E,  0x0C10,  0x0C12,  0x0C28,  0x0C2A,   0x0C33,
   0x0C35,  0x0C39,  0x0C41,  0x0C44,  0x0C60,  0x0C61,  0x0C66,   0x0C6F,
   0x0C82,  0x0C83,  0x0C85,  0x0C8C,  0x0C8E,  0x0C90,  0x0C92,   0x0CA8,
   0x0CAA,  0x0CB3,  0x0CB5,  0x0CB9,  0x0CBE,  0x0CBE,  0x0CC0,   0x0CC4,
   0x0CC7,  0x0CC8,  0x0CCA,  0x0CCB,  0x0CD5,  0x0CD6,  0x0CDE,   0x0CDE,
   0x0CE0,  0x0CE1,  0x0CE6,  0x0CEF,  0x0D02,  0x0D03,  0x0D05,   0x0D0C,
   0x0D0E,  0x0D10,  0x0D12,  0x0D28,  0x0D2A,  0x0D39,  0x0D3E,   0x0D40,
   0x0D46,  0x0D48,  0x0D4A,  0x0D4C,  0x0D57,  0x0D57,  0x0D60,   0x0D61,
   0x0D66,  0x0D6F,  0x0D82,  0x0D83,  0x0D85,  0x0D96,  0x0D9A,   0x0DB1,
   0x0DB3,  0x0DBB,  0x0DBD,  0x0DBD,  0x0DC0,  0x0DC6,  0x0DCF,   0x0DD1,
   0x0DD8,  0x0DDF,  0x0DF2,  0x0DF4,  0x0E01,  0x0E30,  0x0E32,   0x0E33,
   0x0E40,  0x0E46,  0x0E4F,  0x0E5B,  0x0E81,  0x0E82,  0x0E84,   0x0E84,
   0x0E87,  0x0E88,  0x0E8A,  0x0E8A,  0x0E8D,  0x0E8D,  0x0E94,   0x0E97,
   0x0E99,  0x0E9F,  0x0EA1,  0x0EA3,  0x0EA5,  0x0EA5,  0x0EA7,   0x0EA7,
   0x0EAA,  0x0EAB,  0x0EAD,  0x0EB0,  0x0EB2,  0x0EB3,  0x0EBD,   0x0EBD,
   0x0EC0,  0x0EC4,  0x0EC6,  0x0EC6,  0x0ED0,  0x0ED9,  0x0EDC,   0x0EDD,
   0x0F00,  0x0F17,  0x0F1A,  0x0F34,  0x0F36,  0x0F36,  0x0F38,   0x0F38,
   0x0F3E,  0x0F47,  0x0F49,  0x0F6A,  0x0F7F,  0x0F7F,  0x0F85,   0x0F85,
   0x0F88,  0x0F8B,  0x0FBE,  0x0FC5,  0x0FC7,  0x0FCC,  0x0FCF,   0x0FCF,
   0x1000,  0x1021,  0x1023,  0x1027,  0x1029,  0x102A,  0x102C,   0x102C,
   0x1031,  0x1031,  0x1038,  0x1038,  0x1040,  0x1057,  0x10A0,   0x10C5,
   0x10D0,  0x10F8,  0x10FB,  0x10FB,  0x1100,  0x1159,  0x115F,   0x11A2,
   0x11A8,  0x11F9,  0x1200,  0x1206,  0x1208,  0x1246,  0x1248,   0x1248,
   0x124A,  0x124D,  0x1250,  0x1256,  0x1258,  0x1258,  0x125A,   0x125D,
   0x1260,  0x1286,  0x1288,  0x1288,  0x128A,  0x128D,  0x1290,   0x12AE,
   0x12B0,  0x12B0,  0x12B2,  0x12B5,  0x12B8,  0x12BE,  0x12C0,   0x12C0,
   0x12C2,  0x12C5,  0x12C8,  0x12CE,  0x12D0,  0x12D6,  0x12D8,   0x12EE,
   0x12F0,  0x130E,  0x1310,  0x1310,  0x1312,  0x1315,  0x1318,   0x131E,
   0x1320,  0x1346,  0x1348,  0x135A,  0x1361,  0x137C,  0x13A0,   0x13F4,
   0x1401,  0x1676,  0x1681,  0x169A,  0x16A0,  0x16F0,  0x1700,   0x170C,
   0x170E,  0x1711,  0x1720,  0x1731,  0x1735,  0x1736,  0x1740,   0x1751,
   0x1760,  0x176C,  0x176E,  0x1770,  0x1780,  0x17B6,  0x17BE,   0x17C5,
   0x17C7,  0x17C8,  0x17D4,  0x17DA,  0x17DC,  0x17DC,  0x17E0,   0x17E9,
   0x1810,  0x1819,  0x1820,  0x1877,  0x1880,  0x18A8,  0x1E00,   0x1E9B,
   0x1EA0,  0x1EF9,  0x1F00,  0x1F15,  0x1F18,  0x1F1D,  0x1F20,   0x1F45,
   0x1F48,  0x1F4D,  0x1F50,  0x1F57,  0x1F59,  0x1F59,  0x1F5B,   0x1F5B,
   0x1F5D,  0x1F5D,  0x1F5F,  0x1F7D,  0x1F80,  0x1FB4,  0x1FB6,   0x1FBC,
   0x1FBE,  0x1FBE,  0x1FC2,  0x1FC4,  0x1FC6,  0x1FCC,  0x1FD0,   0x1FD3,
   0x1FD6,  0x1FDB,  0x1FE0,  0x1FEC,  0x1FF2,  0x1FF4,  0x1FF6,   0x1FFC,
   0x200E,  0x200E,  0x2071,  0x2071,  0x207F,  0x207F,  0x2102,   0x2102,
   0x2107,  0x2107,  0x210A,  0x2113,  0x2115,  0x2115,  0x2119,   0x211D,
   0x2124,  0x2124,  0x2126,  0x2126,  0x2128,  0x2128,  0x212A,   0x212D,
   0x212F,  0x2131,  0x2133,  0x2139,  0x213D,  0x213F,  0x2145,   0x2149,
   0x2160,  0x2183,  0x2336,  0x237A,  0x2395,  0x2395,  0x249C,   0x24E9,
   0x3005,  0x3007,  0x3021,  0x3029,  0x3031,  0x3035,  0x3038,   0x303C,
   0x3041,  0x3096,  0x309D,  0x309F,  0x30A1,  0x30FA,  0x30FC,   0x30FF,
   0x3105,  0x312C,  0x3131,  0x318E,  0x3190,  0x31B7,  0x31F0,   0x321C,
   0x3220,  0x3243,  0x3260,  0x327B,  0x327F,  0x32B0,  0x32C0,   0x32CB,
   0x32D0,  0x32FE,  0x3300,  0x3376,  0x337B,  0x33DD,  0x33E0,   0x33FE,
   0x3400,  0x4DB5,  0x4E00,  0x9FA5,  0xA000,  0xA48C,  0xAC00,   0xD7A3,
   0xD800,  0xFA2D,  0xFA30,  0xFA6A,  0xFB00,  0xFB06,  0xFB13,   0xFB17,
   0xFF21,  0xFF3A,  0xFF41,  0xFF5A,  0xFF66,  0xFFBE,  0xFFC2,   0xFFC7,
   0xFFCA,  0xFFCF,  0xFFD2,  0xFFD7,  0xFFDA,  0xFFDC,  0x10300,  0x1031E,
   0x10320, 0x10323, 0x10330, 0x1034A, 0x10400, 0x10425, 0x10428,  0x1044D,
   0x1D000, 0x1D0F5, 0x1D100, 0x1D126, 0x1D12A, 0x1D166, 0x1D16A,  0x1D172,
   0x1D183, 0x1D184, 0x1D18C, 0x1D1A9, 0x1D1AE, 0x1D1DD, 0x1D400,  0x1D454,
   0x1D456, 0x1D49C, 0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A2, 0x1D4A5,  0x1D4A6,
   0x1D4A9, 0x1D4AC, 0x1D4AE, 0x1D4B9, 0x1D4BB, 0x1D4BB, 0x1D4BD,  0x1D4C0,
   0x1D4C2, 0x1D4C3, 0x1D4C5, 0x1D505, 0x1D507, 0x1D50A, 0x1D50D,  0x1D514,
   0x1D516, 0x1D51C, 0x1D51E, 0x1D539, 0x1D53B, 0x1D53E, 0x1D540,  0x1D544,
   0x1D546, 0x1D546, 0x1D54A, 0x1D550, 0x1D552, 0x1D6A3, 0x1D6A8,  0x1D7C9,
   0x20000, 0x2A6D6, 0x2F800, 0x2FA1D, 0xF0000, 0xFFFFD, 0x100000, 0x10FFFD};


BSON_END_DECLS


#endif /* MONGOC_SCRAM_PRIVATE_H */
